package com.bestillet.kyllingogco;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.AsyncTask.Status;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

public class AddActivity extends Activity {
	private ArrayList<MixHeader> headers;
	private ArrayList<MixGroup> groups;
	private ArrayList<Card> cards;
	private ArrayList<Mix> mixes;
	private ArrayList<Mix> mix;
	
	private TextView name, price;
	private ListView list;
	private Button add, back, home, basket;
	private Context context;
	
	private MixArrayAdapter adapter;
	private ShopApplication app;
	private LoadingDialog loading;
	private OptionDialog d;
	private CheckDialog c;
	private AddDialog dialog;
	private ImageTask iTask;
	private MixTask mTask;
	private AddTask aTask;
	private Menu menu;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.add);
		
		context = this;
		
		app = (ShopApplication) getApplicationContext();
		cards = app.getCards();
		
		menu = getIntent().getParcelableExtra("menu");

		name = (TextView) findViewById(R.id.lblAddName);
		price = (TextView) findViewById(R.id.lblAddPrice);
		list = (ListView) findViewById(android.R.id.list);
		
		name.setText(menu.getName().replace("\\n", " "));
		price.setText("Pris " + menu.getPrice() + ",-");

		add = (Button) findViewById(R.id.btnAdd);
		add.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				ArrayList<String> missing = new ArrayList<String>();
				int amount = Integer.parseInt(mix.get(1).getChoice().getFill());
				int extra = 0;
				for (int i = 0; i < mix.size(); i++)
					if (mix.get(i).getExtra() > 0)
						extra += mix.get(i).getExtra() * Integer.parseInt(mix.get(i).getChoice().getFill());
				
				Item item = new Item(menu, amount);
				for (int i = 2; i < mixes.size(); i++) {
					if (mixes.get(i).getType() != 2 && !mixes.get(i).isHeader())
						if (!mixes.get(i).getChoice().isSelectable())
							missing.add(mixes.get(i).getNavn());
					item.addMix(mixes.get(i));
				}
				
				for (int i = 0; i < headers.size(); i++) {
					for (int j = 0; j < headers.get(i).getMix().size(); j++)
						if (!headers.get(i).getMix().get(j).getChoice().isSelectable())
							missing.add(headers.get(i).getMix().get(j).getNavn());
					item.addHeader(headers.get(i));
				}
				
				for (int i = 0; i < groups.size(); i++) {
					MixGroup g = groups.get(i);
					int antal = Integer.parseInt(mixes.get(1).getChoice().getFill()) * (g.getAntal() + extra);
					int valgt = 0;
					
					for (int j = 0; j < g.getMix().size(); j++) {
						valgt += Integer.parseInt(g.getMix().get(j).getChoice().getFill());
					}
					
					if (antal != valgt)
						missing.add(g.getNavn());
					item.addGroup(g);
				}
				
				if (missing.size() > 0) {
					String s = "";
					for (int i = 0; i < missing.size(); i++) {
						if (i == missing.size() - 1 && i > 0)
							s += " og ";
						else if (i > 0)
							s += ", ";
						s += missing.get(i);
					}
					dialog = new AddDialog(v.getContext(), s);
					dialog.show();
				} else {
					aTask = new AddTask();
					aTask.execute(item);
					loading = new LoadingDialog(context);
					loading.show();
					//app.addItem(item);
					//Intent intent = new Intent(v.getContext(), BasketActivity.class);
					//startActivity(intent);
				}
			}
		});
		
		back = (Button) findViewById(R.id.btnAddBack);
		back.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				finish();
			}
		});
		
		home = (Button) findViewById(R.id.btnAddHome);
		home.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent intent = new Intent(v.getContext(), CategoryActivity.class);
				intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
				startActivity(intent);
			}
		});
		
		basket = (Button) findViewById(R.id.btnAddBasket);
		basket.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent intent = new Intent(v.getContext(), BasketActivity.class);
				startActivity(intent);
			}
		});
		
		list.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
				switch (mix.get(position).getType()) {
				case 1:
					d = new OptionDialog(v.getContext(), mix.get(position));
					d.show();
					break;
				case 2:
					c = new CheckDialog(v.getContext(), position, mix.get(position));
					c.show();
					break;
				default:
					d = new OptionDialog(v.getContext(), mix.get(position));
					d.show();
					break;
				}
			}
		});
		
		loading = new LoadingDialog(this);
		loading.show();
		
		/*if (menu.getImage() == null) {
			Bitmap b = app.getBitmapFromMemCache(menu.getPicturenormal());
			if (b != null) {
				if (b.isRecycled()) {
					iTask = new ImageTask();
					iTask.execute();
				} else {
					image.setImageBitmap(b);
				}
			} else {
				iTask = new ImageTask();
				iTask.execute();
			}
		}*/
		
		mTask = new MixTask();
		mTask.execute();
	}
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
		
		/*if (menu.getImage() != null)
			menu.getImage().recycle();*/
		
		if (mTask != null)
			if (mTask.getStatus() == Status.RUNNING)
				mTask.cancel(true);
		
		if (iTask != null)
			if (iTask.getStatus() == Status.RUNNING)
				iTask.cancel(true);
		
		if (aTask != null)
			if (aTask.getStatus() == Status.RUNNING)
				aTask.cancel(true);
	}
	
	public void updateChoices() {
		getPrice();
		adapter.notifyDataSetChanged();
	}
	
	public void getPrice() {
		int amount = Integer.parseInt(mix.get(1).getChoice().getFill());
		int result = menu.getPrice();
		
		for (int i = 1; i < mix.size(); i++) {
			Mix m = mix.get(i);
			if (!m.isHeader()) {
				switch (m.getType()) {
				case 1:
					result += m.getChoice().getPrice();
					break;
				case 2:
					for (int j = 0; j < m.getChoices().size(); j++)
						result += m.getChoices().get(j).getPrice();
					break;
				default:
					result += m.getChoice().getPrice();
					break;
				}
			}
		}
		
		price.setText("Pris " + (result * amount) + ",-");
	}

	@Override
	public boolean onCreateOptionsMenu(android.view.Menu menu) {
		menu.add(android.view.Menu.NONE, -2, 0, "Info");
		menu.add(android.view.Menu.NONE, -1, 0, "Indstillinger");
		menu.add(android.view.Menu.NONE, 0, 0, "Tidligere ordrer");
		for (int i = 0; i < cards.size(); i++)
			menu.add(android.view.Menu.NONE, cards.get(i).getIdx(), cards.get(i).getPosition() + 1, cards.get(i).getName());
		return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case -2:
			Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://m.kyllingogco.dk/kontakt.asp?shopid=" + app.getShop().getIdx()));
			startActivity(browserIntent);
			break;
		case -1:
			Intent customer = new Intent(this, CustomerActivity.class);
			startActivity(customer);
			break;
		case 0:
			Intent order = new Intent(this, OrderActivity.class);
			startActivity(order);
			break;
		default:
			Intent card = new Intent(this, CardActivity.class);
			card.putExtra("idx", item.getItemId());
			card.putExtra("title", item.getTitle());
			startActivity(card);
			break;
		}
    	return true;
	}
	
	private void setListHeight() {
		int height = 0;
		
		for (int i = 0; i < adapter.getCount(); i++) {
			View v = adapter.getView(i, null, list);
			v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
			height += v.getMeasuredHeight();
		}
		
		ViewGroup.LayoutParams params = list.getLayoutParams();
		params.height = height + (list.getDividerHeight() * (adapter.getCount() - 1));
		list.setLayoutParams(params);
		list.requestLayout();
	}
	
	private class MixTask extends AsyncTask<Void, Void, Boolean> {
    	@Override
		protected Boolean doInBackground(Void... params) {
    		try {
    			InputStream in = Server.post(Server.MIX, Server.getAuthenticationMix(context, menu.getMixidx()));
    			XmlPullParser parser = Server.toXmlParser(in);
    			mixes = XmlParser.getMix(parser);
    			mixes.add(0, new Mix("valg", "Valg", true, -1, 1, 0));
    			mixes.add(1, getAntal());
    			
    			in = Server.post(Server.GROUPS, Server.getAuthenticationMixGroups(context, menu.getMixgroup()));
    			parser = Server.toXmlParser(in);
    			groups = XmlParser.getMixGroup(parser);
    			
    			in = Server.post(Server.HEADER, Server.getAuthenticationMixHeaders(context, menu.getMixheader()));
    			parser = Server.toXmlParser(in);
    			headers = XmlParser.getMixHeader(parser);
    			
    			in.close();
    		} catch (IOException e) {
    			Log.e("Shop", "IOException: " + e.getMessage());
    			return false;
    		} catch (XmlPullParserException e) {
    			Log.e("Shop", "XmlPullParserException: " + e.getMessage());
    			return false;
    		} catch (NullPointerException e) {
    			Log.e("Shop", "NullPointerException: " + e.getMessage());
    			return false;
    		} catch (IllegalArgumentException e) {
    			Log.e("Shop", "IllegalArgumentException: " + e.getMessage());
    			return false;
    		}
    		return true;
    	}
    
	    @Override
	    protected void onPostExecute(Boolean success) {
	    	if (success) {
	    		mix = new ArrayList<Mix>(mixes);
	    		
	    		for (int i = 0; i < headers.size(); i++) {
	    			MixHeader h = headers.get(i);
	    			mix.add(h);
	    			for (int j = 0; j < h.getMix().size(); j++)
	    				mix.add(h.getMix().get(j));
	    		}
	    		
	    		for (int i = 0; i < groups.size(); i++) {
	    			MixGroup g = groups.get(i);
	    			mix.add(g);
	    			for (int j = 0; j < g.getMix().size(); j++)
	    				mix.add(g.getMix().get(j));
	    		}
	    		
    			for (int i = 0; i < mix.size(); i++)
    				if (mix.get(i).getType() == 1 && !mix.get(i).isHeader())
    					mix.get(i).setChoice(mix.get(i).getOptions().get(0));
    				
    			adapter = new MixArrayAdapter(context, mix);
				list.setAdapter(adapter);
				setListHeight();
	    	} else {
	    		AlertDialog.Builder builder = new AlertDialog.Builder(context);
	    		builder.setMessage(R.string.error_mix)
	    		       .setTitle(R.string.error)
	    		       .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) {
								mTask = new MixTask();
								mTask.execute();
								loading.show();
							}
						})
						.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) {
								finish();
							}
						});
	    		AlertDialog dialog = builder.create();
	    		dialog.show();
	    	}
			loading.dismiss();
	    }
		
		private Mix getAntal() {
			Mix m = new Mix("antal", "Antal", false, -1, 1, 0);
			for (int i = 0; i < 20; i++)
				m.addOption(new Option("" + (i + 1), true, -1, 0));
			return m;
		}
	}
	
	private class ImageTask extends AsyncTask<Void, Void, Boolean> {
    	private Bitmap b;
		
		@Override
		protected Boolean doInBackground(Void... params) {
    		try {
    			InputStream in = Server.get(Server.PRODUCT_IMAGES + menu.getPicturenormal());
    			b = Server.downloadBitmap(in, (Activity)context);
    			in.close();
    			menu.setImage(b);
    			app.addBitmapToMemoryCache(menu.getPicturenormal(), b);
			} catch (IOException e) {
    			Log.e("Shop", "IOException: " + e.getMessage());
				return false;
			} catch (NullPointerException e) {
    			Log.e("Shop", "NullPointerException: " + e.getMessage());
				return false;
			} catch (OutOfMemoryError e) {
    			Log.e("Shop", "OutOfMemoryError: " + e.getMessage());
				return false;
			}
    		return true;
    	}
    
	    @Override
	    protected void onPostExecute(Boolean success) {
	    	if (success) {
    			runOnUiThread(new Runnable() {
    				@Override
    				public void run() {
    					/*try {
	    	    			image.setImageBitmap(b);
    					} catch (NullPointerException e) {
    						Log.e("Shop", "NullPointerException: " + e.getMessage());
    					}*/
    				}
    			});
	    	}
	    }
    }
	
	private class AddTask extends AsyncTask<Item, Void, Boolean> {
		private Item item;
		
		@Override
		protected Boolean doInBackground(Item... params) {
    		try {
    			item = params[0];
    			InputStream in = Server.post(Server.ADD, Server.getBasketItemXml(app.getShop().getIdx(), app.getBasketId(), item));
    			XmlPullParser parser = Server.toXmlParser(in);
    			XmlParser.getItemId(parser);
    			in.close();
			} catch (IOException e) {
    			Log.e("Shop", "IOException: " + e.getMessage());
				return false;
			} catch (NullPointerException e) {
    			Log.e("Shop", "NullPointerException: " + e.getMessage());
				return false;
			} catch (XmlPullParserException e) {
				Log.e("Shop", "XmlPullParserException: " + e.getMessage());
				return false;
			} catch (IllegalArgumentException e) {
				Log.e("Shop", "IllegalArgumentException: " + e.getMessage());
				return false;
			}
    		return true;
    	}
    
	    @Override
	    protected void onPostExecute(Boolean success) {
			loading.dismiss();
	    	if (success) {
	    		Intent intent = new Intent(context, BasketActivity.class);
				startActivity(intent);
	    	} else {
	    		AlertDialog.Builder builder = new AlertDialog.Builder(context);
	    		builder.setMessage(R.string.error_add)
	    		       .setTitle(R.string.error)
	    		       .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) {
								aTask = new AddTask();
								aTask.execute(item);
								loading.show();
							}
						})
						.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) { }
						});
	    		AlertDialog dialog = builder.create();
	    		dialog.show();
	    	}
	    }
    }
}
